﻿
Imports std

Namespace internalFunctions
    'parameters, name, the function name
    '            p0 ... pn, the input parameters to the function
    'return, var, the return from function
    Public Class netmethodcall
        Inherits name_object_ps_function(Of Object)

        Public Sub New()
            MyBase.New(".net.call")
        End Sub

        Protected Overloads Overrides Function invoke(ByVal ctx As context, ByVal name As String, _
                                                      ByVal ps As vector(Of Object), ByRef o As Object) As Boolean
            Dim m As Reflection.MethodInfo = Nothing
            If loadmethod(name, m) Then
                Return _reflection.invoke(m, ps, o)
            Else
                raiseError("no function found " + name, errorHandle.errorType.user)
                Return False
            End If
        End Function

        Protected Overrides Function returnType() As typeDefination
            Return typeDefination.var
        End Function
    End Class

    'parameters, filename, the dll file name
    '            namespace, optional
    '            class, can include namespace, separate by .
    '            output, pointer<var>, the type returned
    'return, bool, whether load is success or not
    Public Class netloadclass
        Inherits templateFunction(Of Boolean)

        Public Class parameters
            Public Const filename As String = "filename"
            Public Const [namespace] As String = "namespace"
            Public Const [class] As String = "class"
            Public Const output As String = "output"
        End Class

        Private Shared m As iParametersMapping = Nothing

        Shared Sub New()
            initialMapping(m, parameters.filename, parameters.class, parameters.output)
        End Sub

        Public Sub New()
            MyBase.New(".net.loadclass", m)
        End Sub

        Protected Overrides Function invoke(ByVal ctx As context, ByRef rtn As Boolean) As Boolean
            Dim output As pointer(Of pointer(Of Object)) = Nothing
            If ctx.findVariable(parameters.output, output) Then
                Dim filename As String = Nothing
                If ctx.findVariableStr(parameters.filename, filename) Then
                    Dim [namespace] As String = Nothing
                    [namespace] = ctx.findVariableStr(parameters.namespace)
                    Dim [class] As String = Nothing
                    If ctx.findVariableStr(parameters.class, [class]) Then
                        Dim t As Type = Nothing
                        If [namespace] Is Nothing Then
                            rtn = loadclass(filename, [class], t)
                        Else
                            rtn = loadclass(filename, [namespace], [class], t)
                        End If
                        If rtn Then
                            output.instance().setinstance(t)
                        End If
                        Return True
                    Else
                        raiseError("expect parameter " + parameters.class, errorHandle.errorType.user)
                        Return False
                    End If
                Else
                    raiseError("expect parameter " + parameters.filename, errorHandle.errorType.user)
                    Return False
                End If
            Else
                raiseError("expect parameter " + parameters.output, errorHandle.errorType.user)
                Return False
            End If
        End Function

        Protected Overrides Function returnType() As typeDefination
            Return typeDefination.bool
        End Function
    End Class

    'parameters, class, the class returned by .net.loadclass
    '            method, the method name
    '            output, the method return
    'return, bool, whether success or not
    Public Class netloadmethodfromclass
        Inherits templateFunction(Of Boolean)

        Public Class parameters
            Public Const [class] As String = "class"
            Public Const method As String = "method"
            Public Const output As String = "output"
        End Class

        Private Shared m As iParametersMapping = Nothing

        Shared Sub New()
            initialMapping(m, parameters.class, parameters.method, parameters.output)
        End Sub

        Public Sub New()
            MyBase.New(".net.loadmethod.fromclass", m)
        End Sub

        Protected Overrides Function invoke(ByVal ctx As context, ByRef rtn As Boolean) As Boolean
            Dim [class] As Type = Nothing
            If ctx.findVariable(parameters.class, [class]) Then
                Dim output As pointer(Of pointer(Of Object)) = Nothing
                If ctx.findVariable(parameters.output, output) Then
                    Dim method As String = Nothing
                    If ctx.findVariable(parameters.method, method) Then
                        Dim m As Reflection.MethodInfo = Nothing
                        rtn = loadmethod([class], method, m)
                        If rtn Then
                            output.instance().setinstance(m)
                        End If
                        Return True
                    Else
                        raiseError("expect parameter " + parameters.method, errorHandle.errorType.user)
                        Return False
                    End If
                Else
                    raiseError("expect parameter " + parameters.output, errorHandle.errorType.user)
                    Return False
                End If
            Else
                raiseError("expect parameter " + parameters.class, errorHandle.errorType.user)
                Return False
            End If
        End Function

        Protected Overrides Function returnType() As typeDefination
            Return typeDefination.bool
        End Function
    End Class

    Public Class netinvoke
        Inherits x_object_ps_function(Of Reflection.MethodInfo, Object)

        Public Sub New()
            MyBase.new(".net.invoke")
        End Sub

        Protected Overloads Overrides Function invoke(ByVal ctx As context, ByVal x As Reflection.MethodInfo, _
                                                      ByVal ps As vector(Of Object), ByRef o As Object) As Boolean
            Return _reflection.invoke(x, ps, o)
        End Function

        Protected Overrides Function returnType() As typeDefination
            Return typeDefination.var
        End Function

        Protected Overrides Function x_finder() As iVariableFinder(Of Reflection.MethodInfo)
            Return methodInfo_finder()
        End Function
    End Class

    Public Class netloadmethod
        Inherits templateFunction(Of Boolean)

        Public Class parameters
            Public Const filename As String = "filename"
            Public Const [namespace] As String = "namespace"
            Public Const [class] As String = "class"
            Public Const method As String = "method"
            Public Const output As String = "output"
        End Class

        Private Shared m As iParametersMapping = Nothing

        Shared Sub New()
            initialMapping(m, parameters.filename, parameters.method, parameters.output)
        End Sub

        Public Sub New()
            MyBase.New(".net.loadmethod", m)
        End Sub

        Protected Overrides Function invoke(ByVal ctx As context, ByRef o As Boolean) As Boolean
            Dim filename As String = Nothing
            If ctx.findVariableStr(parameters.filename, filename) Then
                Dim [namespace] As String = Nothing
                [namespace] = ctx.findVariableStr(parameters.namespace)
                Dim [class] As String = Nothing
                [class] = ctx.findVariableStr(parameters.class)
                Dim method As String = Nothing
                If ctx.findVariableStr(parameters.method, method) Then
                    Dim output As pointer(Of pointer(Of Object)) = Nothing
                    If ctx.findVariable(parameters.output, output) Then
                        Dim m As Reflection.MethodInfo = Nothing
                        If Not [class] Is Nothing Then
                            If Not [namespace] Is Nothing Then
                                o = loadmethod(filename, [namespace], [class], method, m)
                            Else
                                o = loadmethod(filename, [class], method, m)
                            End If
                        Else
                            o = loadmethod(filename, method, m)
                        End If
                        If o Then
                            output.instance().setinstance(m)
                        End If

                        Return True
                    Else
                        raiseError("expect parameter " + parameters.output, errorHandle.errorType.user)
                        Return False
                    End If
                Else
                    raiseError("expect parameter " + parameters.method, errorHandle.errorType.user)
                    Return False
                End If
            Else
                raiseError("expect parameter " + parameters.filename, errorHandle.errorType.user)
                Return False
            End If
        End Function

        Protected Overrides Function returnType() As _types.typeDefination
            Return typeDefination.bool
        End Function
    End Class
End Namespace